package org.linlinjava.litemall.core.util;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.lang.reflect.Field;
import java.util.List;
/**
 * 响应操作结果
 * <pre>
 *  {
 *      errno： 错误码，
 *      errmsg：错误消息，
 *      data：  响应数据
 *  }
 * </pre>
 *
 * <p>
 * 错误码：
 * <ul>
 * <li> 0，成功；
 * <li> 4xx，前端错误，说明前端开发者需要重新了解后端接口使用规范：
 * <ul>
 * <li> 401，参数错误，即前端没有传递后端需要的参数；
 * <li> 402，参数值错误，即前端传递的参数值不符合后端接收范围。
 * </ul>
 * <li> 5xx，后端错误，除501外，说明后端开发者应该继续优化代码，尽量避免返回后端错误码：
 * <ul>
 * <li> 501，验证失败，即后端要求用户登录；
 * <li> 502，系统内部错误，即没有合适命名的后端内部错误；
 * <li> 503，业务不支持，即后端虽然定义了接口，但是还没有实现功能；
 * <li> 504，更新数据失效，即后端采用了乐观锁更新，而并发更新时存在数据更新失效；
 * <li> 505，更新数据失败，即后端数据库更新失败（正常情况应该更新成功）。
 * </ul>
 * <li> 6xx，小商城后端业务错误码，
 * 具体见litemall-admin-api模块的AdminResponseCode。
 * <li> 7xx，管理后台后端业务错误码，
 * 具体见litemall-wx-api模块的WxResponseCode。
 * </ul>
 */
public class ResponseUtil {

    public static <T> Response<T> ok() {
        return new Response<>(0, "成功", null);
    }

    public static <T> Response<T> ok(T data) {
    	 return new Response<>(0, "成功", data);
    }



    public static <T> Response<T> success(T data) {
        return new Response<>(0, "succeed", data);
    }

    public static <T> Response<T> fail(int code, String errmsg,T data) {
        return new Response<>(code, StrUtil.isNotBlank(errmsg)?errmsg:"错误",data);
    }

    //转换mybatis-plus分页 兼容老版本格式
    public static <T> Response okPage(IPage<T> page){
        if(page==null){return ok(new ListResponse<>());}
        ListResponse<T> listResponse = new ListResponse<>();
        listResponse.setList(page.getRecords());
        listResponse.setTotal(page.getTotal());
        listResponse.setPage(page.getSize());
        listResponse.setLimit(page.getCurrent());
        listResponse.setPages(page.getPages());
        return ok(listResponse);
    }

    public static <T> Response okPage(IPage<T> page,List list){
        if(page==null){return ok(new ListResponse<>());}
        ListResponse<T> listResponse = new ListResponse<>();
        listResponse.setList(list);
        listResponse.setTotal(page.getTotal());
        listResponse.setPage(page.getSize());
        listResponse.setLimit(page.getCurrent());
        listResponse.setPages(page.getPages());
        return ok(listResponse);
    }

    //mybatis-plus集成pagehelper分页
    public static <T> Response okPageInfo(List<T> list){
        //PageInfo pageInfo = new PageInfo<>(list);
        return success(list);
    }

    public static <T> Response<ListResponse<T>> okList(List<T> list) {
        ListResponse<T> listResponse = new ListResponse<>();
        listResponse.setList(list);
        /*if (list instanceof Page) {
            Page page = (Page) list;
            listResponse.setTotal(page.getTotal());
            listResponse.setPage(page.getPageNum());
            listResponse.setLimit(page.getPageSize());
            listResponse.setPages(page.getPages());
        } else {
        	listResponse.setTotal(list.size());
            listResponse.setPage(1);
            listResponse.setLimit(list.size());
            listResponse.setPages(1);
        }*/
        return ok(listResponse);
    }

    public static <T> Response<ListResponse<T>> okList(List<T> list, List pagedList) {
        ListResponse<T> listResponse = new ListResponse<>();
        listResponse.setList(list);
        /*if (pagedList instanceof Page) {
            Page page = (Page) pagedList;
            listResponse.setTotal(page.getTotal());
            listResponse.setPage(page.getPageNum());
            listResponse.setLimit(page.getPageSize());
            listResponse.setPages(page.getPages());
        } else {
        	listResponse.setTotal(pagedList.size());
            listResponse.setPage(1);
            listResponse.setLimit(pagedList.size());
            listResponse.setPages(1);
        }*/

        return ok(listResponse);
    }

    public static <T> Response<T> fail() {
        return fail(-1, "错误");
    }

    public static <T> Response<T> fail(int errno, String errmsg) {
        return new Response<>(errno, errmsg, null);
    }

    public static <T> Response<T> fail(Object object) {
        try{
            Field codeField = object.getClass().getDeclaredField("code");
            codeField.setAccessible(true); // 私有属性必须设置访问权限
            Object codeObj = codeField.get(object);
            Integer code = 0;
            if(codeObj instanceof Integer){
                code = (Integer)codeObj;
            }

            Field nameField = object.getClass().getDeclaredField("msg");
            nameField.setAccessible(true); // 私有属性必须设置访问权限
            Object nameObj = nameField.get(object);
            String name= "";
            if(nameObj instanceof String){
                name = (String)nameObj;
            }

            return fail(code, name);

        }catch (Exception e){
            return fail();
        }
    }
    
    public static class Response<T> {
    	
    	private int errno;
    	
    	private String errmsg;
    	
    	private T data;
    	
    	public Response (int errno, String errmsg, T data) {
    		this.errno = errno;
    		this.errmsg = errmsg;
    		this.data = data;
    	}

		public int getErrno() {
			return errno;
		}

		public void setErrno(int errno) {
			this.errno = errno;
		}

		public String getErrmsg() {
			return errmsg;
		}

		public void setErrmsg(String errmsg) {
			this.errmsg = errmsg;
		}

		public T getData() {
			return data;
		}

		public void setData(T data) {
			this.data = data;
		}

        @Override
        public String toString() {
            return "Response{" +
                    "errno=" + errno +
                    ", errmsg='" + errmsg + '\'' +
                    ", data=" + data +
                    '}';
        }
    }
    
    public static class ListResponse<T> {
    	
    	private long total;
    	
    	private long page;
    	
    	private long limit;
    	
    	private long pages;
    	
    	private List<T> list;

		public long getTotal() {
			return total;
		}

		public void setTotal(long total) {
			this.total = total;
		}

		public long getPage() {
			return page;
		}

		public void setPage(long page) {
			this.page = page;
		}

		public long getLimit() {
			return limit;
		}

		public void setLimit(long limit) {
			this.limit = limit;
		}

		public long getPages() {
			return pages;
		}

		public void setPages(long pages) {
			this.pages = pages;
		}

		public List<T> getList() {
			return list;
		}

		public void setList(List<T> list) {
			this.list = list;
		}
		
    }

    public static <T> Response<T> badArgument() {
        return fail(401, "参数不对");
    }

    public static <T> Response<T> badArgument(Integer code , String msg) {
        return fail(code, msg);
    }

    public static <T> Response<T> badArgument(Object object) {
        return fail(object);

    }

    public static <T> Response<T> badArgumentValue() {
        return fail(402, "参数值不对");
    }

    public static <T> Response<T> unlogin() {
        return fail(501, "请登录");
    }

    public static <T> Response<T> serious() {
        return fail(502, "系统内部错误");
    }

    public static <T> Response<T> unsupport() {
        return fail(503, "业务不支持");
    }

    public static <T> Response<T> updatedDateExpired() {
        return fail(504, "更新数据已经失效");
    }

    public static <T> Response<T> updatedDataFailed() {
        return fail(505, "更新数据失败");
    }

    public static <T> Response<T> unauthz() {
        return fail(506, "无操作权限");
    }



}

